#include "stdafx.h"
#include "Name.h"

namespace AppliedCryptography
{
	ASN1ObjectIdentifier Name::CN("2.5.4.3");
	ASN1ObjectIdentifier Name::O("2.5.4.10");
	ASN1ObjectIdentifier Name::C("2.5.4.6");

	Name::Name(ClassBits classBits, ConstructedBit constucted, TypeNumberBits number)
		: ASN1Sequence(classBits, constucted, number)
	{
	};

	Name::Name()
	{
	};

	Name::Name(const Name& other)
	{
		unsigned int len = other.size();
		ASN1Sequence *seq;

		for(unsigned int i=0; i<len; ++i)
		{
			seq = new ASN1Sequence(ASN1Sequence::getInstance(*other.getStdContainer()[i]));
			this->getStdContainer().push_back(seq);
		};
	};

	Name::~Name()
	{
		for(unsigned int i=0; i < size(); ++i)
		{
			delete (ASN1Sequence*)getStdContainer()[i];
		};
	};

	ASN1Sequence& Name::add(ASN1Encodable& obj)
	{
		return this->ASN1Sequence::add(obj);
	};

	ASN1Encodable& Name::get(unsigned int index) const
	{
		return this->ASN1Sequence::get(index);
	};

	Name& Name::add(ASN1ObjectIdentifier& oid, ASN1PrintableString& value)
	{
		ASN1Sequence *seq = new ASN1Sequence();

		seq->add(oid);
		seq->add(value);

		getStdContainer().push_back(seq);

		return *this;
	};

	Name& Name::operator=(const Name& other)
	{
		unsigned int len = other.size();
		ASN1Sequence *seq;

		for(unsigned int i=0; i<len; ++i)
		{
			seq = new ASN1Sequence(ASN1Sequence::getInstance(*other.getStdContainer()[i]));
			this->getStdContainer().push_back(seq);
		};

		return *this;
	};

	std::vector<byte> Name::getContentBits() const
	{
		ASN1Set* set = NULL;
		ASN1Sequence seq;
		std::vector<byte> buffer;
		std::vector<ASN1Set*> nameParams;

		for(unsigned int i=0; i<size(); ++i)
		{
			set = new ASN1Set();
			set->add(*getStdContainer()[i]);
			seq.add(*set);
		};

		//return seq.add(set).getContentBits();
		buffer = seq.getContentBits();

		for(unsigned int i=0; i<nameParams.size(); i++)
		{
			delete nameParams[i];
		};

		return buffer;
	};
}; // namespace AppliedCryptography

/*
TEST(Name, Add)
{
	AppliedCryptography::Name name;
	name.add("CN", "some value");
	EXPECT_THROW(name.add("CN", "some other value"), std::exception);
};
*/
